Formation : "Data analyst - Mai 2025 (continue)"
Auteur: Pauline Gomont
Date: "2025-11-12"

The Synthesis Report (SYR) of the IPCC Fifth Assessment Report (AR5) provides an overview of the state of knowledge concerning the science of climate change. It shows that human influence on the climate system is clear, and recent anthropogenic emissions of greenhouse gases are the highest in history. Recent climate changes have had widespread impacts on human and natural systems.
INITIALISATION DU NOTEBOOK¶
Import des librairies nécessaires à l'étude
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import seaborn.objects as so
%matplotlib inline
%load_ext pretty_jupyter
INTRODUCTION¶
Le Groupe d'experts intergouvernmental sur l'évolution du climat (GIEC) est aujourd'hui reconnu comme faisant autorité sur le changement climatique. Fondé en 1998, et composé de 195 états membres de l'ONU, le GIEC a pour objectif de faire un état des connaissances scientifiques, techniques et socio-économiques relatives à ce domaine à travers la publication de rapports. Le dernier rapport d'évaluation date de 20231.
L'influence des êtres humains sur le réchauffement de l'atmosphère, des océans et des contients est sans conteste. Le rythme du réchauffement s'est considérement accéléré ces 50 dernières annnées, et il est sans précédent depuis 2000 ans.
L'émission des gaz à effets de serres est identifiée comme l'un des facteurs ayant le plus de poids dans l'augmentation des températures dont les effets sont intensifiées par la déforestation.
Ce notebook vise à analyser les anomalies des températures observées à la surface de la terre et des océans entre 1880 et 2024, s'appuyant sur les données publiées par le Goddard Institute for Space Studies. Il s'agira d'observer l'évolution des anomalies dans leur distribution sur différentes zones climatiques. Les données de températures seront confrontées par la suite à celles relatives à la consommation mondiale de gaz à effets de serres sur la même période, dans le but d'illustrer des corrélations.
1 Rapport de synthèse AR6 publié par le GIEC - mars 2023 : https://www.ipcc.ch/report/ar6/syr/downloads/report/IPCC_AR6_SYR_SPM.pdf (Consulté le 25/10/2025)
JEUX DE DONNÉES¶
Anomalies de température : GISTEMP¶
Producteur de la source¶
Fondé en 1960 Goddard Institute for Space Studies (GISS) de la NASA effectue des missions de recherches fondamentales dans le domaine des sciences spatiales. Les analyses menées sur l’atmosphère terrestre font aujourd’hui de ce laboratoire un acteur majeur de l’étude des changements climatiques. Le projet GISTEMP (Goddard Institute Surface Temperature Analysis), débuté à la fin des années 1970, consiste à mesurer les températures afin d’en analyser les anomalies, objet principal de ce rapport. Deux types de relevés de mesures sont mis à disposition sur leur site internet 2.
- Land-Ocean Temperature Index (L-OTI) Mesure des anomalies de température (écarts par rapport à une moyenne de référence, généralement 1951–1980) qui combine les températures de l’air en surface au sol et de la mer. Les données couvrent une période allant de 1880 à aujourd’hui et sont actualisées mensuellement.
- Atmospheric Infrared Sounder v6/v7 Temperature (AIRS) Mesure du rayonnement infrarouge émis par l’atmosphère via un instrument embarqué sur le satellite Aqua et dont les mesures sont converties en données sur les températures. Les données couvrent une période allant de 2002 jusqu’à aujourd’hui et sont actualisées quotidiennement.
Ce rapport cherchant à mettre en évidence les changements de températures sur le temps long, les données AIRS ont été écartées de l’analyse bien que plus précises.
Concernant les températures mesurées à la surface des sols, le GISS utilise les données publiées par le Global Historical Climatology Network qui s'appuient sur les relevés d'environ 7000 stations3. Il faut noter une exception pour l’Antarctique, pour lequel les données proviennent du Comité Scientifique des Recherches sur l’Antarctique (SCAR)4. La période de référence pour mesurer les anomalies est 1951-1980, période choisie en climatologie par le Service National de Météorologie des Etats-Unis.
Le GISS utilise seulement les stations éloignées de 1200km pour lesquelles les données couvrent une période commune d'au moins 20 ans.
le GISS retravaille les données brutes, tenant compte par exemple de la luminosité artificielle à laquelle des stations à proximité de milieux urbains peuvent être exposées.
La mesure de la température à la surface des océans quant à elle, se fonde sur les données du Met Office Hadley Center5. Les données couvrent la période de 1850 à aujourd’hui puis elles sont insérées dans les zones géographiques définies dans le modèles GISTEMP.
2 https://data.giss.nasa.gov/gistemp/ [consulté le 17/09/2025].
3 https://www.ncei.noaa.gov/products/land-based-station/global-historical-climatology-network-monthly [consulté le 17/09/2025].
4 http://www.antarctica.ac.uk/met/READER/ [consulté le 17/09/2025].
5 https://www.ncei.noaa.gov/products/extended-reconstructed-sst [consulté le 17/09/2025].
Définition des variables¶
Combined Land-Surface Air and Sea-Surface Water Temperature Anomalies
(Land-Ocean Temperature Index, L-OTI)
Les fichiers présentent les moyennes d'anomalies de température relevées mensuellement, calculées par années et par saisons, en employant pour période de référence les moyennes mesurées pour la période 1951-1980. Le dernier fichier opére un découpage lattitudinal.
Moyennes mensuelles, saisonnières, annuelles¶
- Global-mean monthly, seasonal, and annual means, 1880-present, updated through most recent month: CSV
- Northern Hemisphere-mean monthly, seasonal, and annual means, 1880-present, updated through most recent month: CSV
- Southern Hemisphere-mean monthly, seasonal, and annual means, 1880-present, updated through most recent month: CSV
| Nom | Type | Variable | Remarque |
|---|---|---|---|
| 'Year' | int | qualitative | année au format YYYY : 1880 - 2025 (2024 après traiement) |
| 'Jan' | float | quantitative | relevé des anomalies de Janvier en °C p/r à la période de référence |
| 'Feb' | float | quantitative | relevé des anomalies de Février en °C p/r à la période de référence |
| 'Mar' | float | quantitative | relevé des anomalies de Mars en °C p/r à la période de référence |
| 'Apr' | float | quantitative | relevé des anomalies de Avril en °C p/r à la période de référence |
| 'May' | float | quantitative | relevé des anomalies de Mai en °C p/r à la période de référence |
| 'Jun' | float | quantitative | relevé des anomalies de Juin en °C p/r à la période de référence |
| 'Jul' | float | quantitative | relevé des anomalies de Juillet en °C p/r à la période de référence |
| 'Aug' | float | quantitative | relevé des anomalies de Août en °C p/r à la période de référence |
| 'Sep' | float | quantitative | relevé des anomalies de Septembre en °C p/r à la période de référence |
| 'Oct' | float | quantitative | relevé des anomalies de Octobre en °C p/r à la période de référence |
| 'Nov' | float | quantitative | relevé des anomalies de Novembre en °C p/r à la période de référence |
| 'Dec' | float | quantitative | relevé des anomalies de Décembre en °C p/r à la période de référence |
| 'J-D' | float | quantitative | relevé des anomalies de Janvier-Décembre en °C p/r à la période de référence |
| 'D-N' | float | quantitative | relevé des anomalies de Décembre-Novembre en °C p/r à la période de référence |
| 'DJF' | float | quantitative | relevé des anomalies de Décembre-Février en °C p/r à la période de référence |
| 'MAM' | float | quantitative | relevé des anomalies de Mars-Mai en °C p/r à la période de référence |
| 'JJA' | float | quantitative | relevé des anomalies de Juin-Août en °C p/r à la période de référence |
| 'SON' | float | quantitative | relevé des anomalies de Septembre-Novembre en °C p/r à la période de référence |
Moyennes annuelles par zone¶
- Zonal annual means, 1880-present, updated through most recent complete year: CSV
| Nom | Type | Variable | Remarques | Zone |
|---|---|---|---|---|
| Year | int64 | Quantitative | année au format : 1880-2024 | --- |
| Glob | float64 | Quantitative | relevé des anomalies en °C | monde |
| NHem | float64 | Quantitative | relevé des anomalies en °C | hémisphère nord |
| SHem | float64 | Quantitative | relevé des anomalies en °C | hémisphère sud |
| 24N-90N | float64 | Quantitative | relevé des anomalies en °C | cercle arctique + tropique du Cancer |
| 24S-24N | float64 | Quantitative | relevé des anomalies en °C | tropiques |
| 90S-24S | float64 | Quantitative | relevé des anomalies en °C | cercle antarctique + tropique |
| 64N-90N | float64 | Quantitative | relevé des anomalies en °C | cercle arctique |
| 44N-64N | float64 | Quantitative | relevé des anomalies en °C | extra tropique du cancer |
| 24N-44N | float64 | Quantitative | relevé des anomalies en °C | sub tropique du cancer |
| EQU-24N | float64 | Quantitative | relevé des anomalies en °C | Equateur tropique du cancer |
| 24S-EQU | float64 | Quantitative | relevé des anomalies en °C | tropique du capricorne equateur |
| 44S-24S | float64 | Quantitative | relevé des anomalies en °C | extra tropique capricorne cercle |
| 64S-44S | float64 | Quantitative | relevé des anomalies en °C | subtropique capricorne cercle antarctique |
| 90S-64S | float64 | Quantitative | relevé des anomalies en °C | cercle antarctique |
![]()
Émissions de GES : OWID¶
Producteur de la source¶
Our World in Data est une organisation à but non lucratif, basée en Grande-Bretagne, qui met à disposition des jeux de données relatifs à de grands problèmes mondiaux, tels que la pauvreté, les maladies ou encore le changement climatique 6.
Elle travaille en partenariat avec les universités d’Oxford et de Harvard pour s’assurer de la validation de la méthodologie employée. L’intégralité des données et du code sont disponibles sur la plateforme Github 7.
En 2020, Our World in Data publie un jeu de données sur les émissions de gaz à effet de serre sur la planète. Les données sont régulièrement mises à jour, la version utilisée dans ce rapport est celle du 24 novembre 2024. Ce jeu de données est une agrégation de plusieurs producteurs de données comme le Energy Institute, ou encore le Global Carbon Project. Les données recueillies sur les émissions de gaz sont complétées par des métriques concernant le PIB, le nombre d’habitants par pays.
Définition des données¶
Le jeu de données contient près de 80 variables 8. Seules celles utilisées au cours de l’étude sont détaillées ci-après.
Les émissions de dioxyde de carbone incluant le changement d’utilisation des sols, notamment dû à la déforestation associée à l’artificialisation des sols, sont retenues pour observer plus finement la part de cette action humaine. Celles de protoxyde d’azote, un gaz à effet de serre extrêmement puissant, même majoritairement naturelles permettent néanmoins de cibler le secteur agricole dont les engrais azotés sont la principale source d’émissions d’origine humaine de ce gaz 9. Enfin, les émissions de méthane, reconnu comme le deuxième gaz responsable du réchauffement climatique selon le rapport du GIEC de 1993, mettent en exergue la contribution des secteurs énergétique et agricole 10.
| Nom | Type | Variable | Remarque |
|---|---|---|---|
| co2 | float | quantitative | Émissions annuelles de CO₂ en million de tonnes, excluant les changements d'utilisation des sols |
| co2_including_luc | float | quantitative | Émissions annuelles de CO₂ en million de tonnes, incluant les changements d'utilisation des sols |
| methane | float | quantitative | Émissions annuelles de méthane |
| nitrous_oxide | float | quantitative | Emissions annuelles de protoxyde d'azote |
| total_ghg | float | quantitative | Émissions totales de tous les gazs à effet de serre |
| country | object | qualitative | pays, continent |
| year | int | quantitative | année |
6 https://ourworldindata.org/about [consulté le 17/09/2025].
7 https://github.com/owid [consulté le 17/09/2025].
8 Le codebook est publié sur le projet github https://github.com/owid/co2-data [consulté le 17/09/2025].
9 https://fr.wikipedia.org/wiki/Protoxyde_d%27azote [consulté le 16/09/2025].
10 GIEC, « Changements climatiques 2013, Les éléments scientifiques : Résumé à l'intention des décideurs [archive] », 2013, p.12
Cyclones : IBTrACS¶
Producteur de la source¶
Le projet International Best Track Archive for Climate Stewardship (IBTrACS) a été conçu pour inventorier les cyclones tropicaux signalés dans le monde entier et fournir les données en un seul ensemble mondial. IBTrACS compile et archive les meilleures estimations de la position et de l'intensité des cyclones tropicaux (appelées données best-track) auprès des Centres Météorologiques Spécialisés Régionaux (RSMC) de l'Organisation Météorologique Mondiale (OMM) et d'autres centres d'alerte (TCWC) et organismes nationaux. La première version de ses données en 2008. La version utilisée dans cette analyse est la v04r01. Les données couvrent une période allant de 1842 à 202510.
Définition des variables¶
Le jeu de données contient 174 colonnes dont le détail est fourni ici. Le tableau suivant fait état uniquement des variables utilisées dans cette analyse.
| Nom | type | Variable | Description |
|---|---|---|---|
| SID | object | Qualitative | Identifiant unique du cyclone |
| SEASON | object | Qualitative | Année |
| LAT | object | Qualitative | Latitude |
| NATURE | object | Qualitative | Type de cyclone DS - Disturbance TS - Tropical ET - Extratropical SS - Subtropical NR - Not reported MX - Mixture (contradicting nature reports from different agencies) |
10 https://www.ncei.noaa.gov/products/international-best-track-archive version du 2025-11-06.
IMPORTATION DES DONNEES¶
NASA - Global¶
#import
gbl_loti = pd.read_csv('/content/drive/MyDrive/datascientest_MAI2025/MAI25_CDA_TEMP-TERRESTRE/Livrables/Donnees/NASA/Loti/GLB.Ts+dSST.csv', header=1)
print("fichier : GLB.Ts+dSST.csv")
print(f"le dataframe gbl_loti se compose de {gbl_loti.shape[0]} lignes et de {gbl_loti.shape[1]} colonnes")
print('\n')
print(gbl_loti.info())
fichier : GLB.Ts+dSST.csv le dataframe gbl_loti se compose de 146 lignes et de 19 colonnes <class 'pandas.core.frame.DataFrame'> RangeIndex: 146 entries, 0 to 145 Data columns (total 19 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 146 non-null int64 1 Jan 146 non-null float64 2 Feb 146 non-null float64 3 Mar 146 non-null float64 4 Apr 146 non-null float64 5 May 146 non-null float64 6 Jun 146 non-null float64 7 Jul 146 non-null float64 8 Aug 146 non-null object 9 Sep 146 non-null object 10 Oct 146 non-null object 11 Nov 146 non-null object 12 Dec 146 non-null object 13 J-D 146 non-null object 14 D-N 146 non-null object 15 DJF 146 non-null object 16 MAM 146 non-null float64 17 JJA 146 non-null object 18 SON 146 non-null object dtypes: float64(8), int64(1), object(10) memory usage: 21.8+ KB None
NASA - Hémisphère Nord¶
#import
nh_loti=pd.read_csv('/content/drive/MyDrive/datascientest_MAI2025/MAI25_CDA_TEMP-TERRESTRE/Livrables/Donnees/NASA/Loti/NH.Ts+dSST.csv', header=1)
print("fichier: 'NH.Ts+dSST.csv'")
print(f"le dataframe nh_loti se compose de {nh_loti.shape[0]} lignes et de {nh_loti.shape[1]} colonnes")
print('\n')
print(nh_loti.info())
fichier: 'NH.Ts+dSST.csv' le dataframe nh_loti se compose de 146 lignes et de 19 colonnes <class 'pandas.core.frame.DataFrame'> RangeIndex: 146 entries, 0 to 145 Data columns (total 19 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 146 non-null int64 1 Jan 146 non-null float64 2 Feb 146 non-null float64 3 Mar 146 non-null float64 4 Apr 146 non-null float64 5 May 146 non-null float64 6 Jun 146 non-null float64 7 Jul 146 non-null object 8 Aug 146 non-null object 9 Sep 146 non-null object 10 Oct 146 non-null object 11 Nov 146 non-null object 12 Dec 146 non-null object 13 J-D 146 non-null object 14 D-N 146 non-null object 15 DJF 146 non-null object 16 MAM 146 non-null float64 17 JJA 146 non-null object 18 SON 146 non-null object dtypes: float64(7), int64(1), object(11) memory usage: 21.8+ KB None
NASA - Hémisphère Sud¶
#import
sh_loti=pd.read_csv('/content/drive/MyDrive/datascientest_MAI2025/MAI25_CDA_TEMP-TERRESTRE/Livrables/Donnees/NASA/Loti/SH.Ts+dSST.csv', header=1)
print("fichier: 'SH.Ts+dSST.csv'")
print(f"le dataframe sh_loti se compose de {sh_loti.shape[0]} lignes et de {sh_loti.shape[1]} colonnes")
print('\n')
print(sh_loti.info())
fichier: 'SH.Ts+dSST.csv' le dataframe sh_loti se compose de 146 lignes et de 19 colonnes <class 'pandas.core.frame.DataFrame'> RangeIndex: 146 entries, 0 to 145 Data columns (total 19 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 146 non-null int64 1 Jan 146 non-null float64 2 Feb 146 non-null float64 3 Mar 146 non-null float64 4 Apr 146 non-null float64 5 May 146 non-null float64 6 Jun 146 non-null float64 7 Jul 146 non-null object 8 Aug 146 non-null object 9 Sep 146 non-null object 10 Oct 146 non-null object 11 Nov 146 non-null object 12 Dec 146 non-null object 13 J-D 146 non-null object 14 D-N 146 non-null object 15 DJF 146 non-null object 16 MAM 146 non-null float64 17 JJA 146 non-null object 18 SON 146 non-null object dtypes: float64(7), int64(1), object(11) memory usage: 21.8+ KB None
NASA - Zones¶
#import
za_loti=pd.read_csv('/content/drive/MyDrive/datascientest_MAI2025/MAI25_CDA_TEMP-TERRESTRE/Livrables/Donnees/NASA/Loti/ZonAnn.Ts+dSST.csv')
print("fichier: 'ZonAnn.Ts+dSST.csv'")
print(f"le dataframe za_loti se compose de {za_loti.shape[0]} lignes et de {za_loti.shape[1]} colonnes")
print('\n')
print(za_loti.info())
fichier: 'ZonAnn.Ts+dSST.csv' le dataframe za_loti se compose de 145 lignes et de 15 colonnes <class 'pandas.core.frame.DataFrame'> RangeIndex: 145 entries, 0 to 144 Data columns (total 15 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 145 non-null int64 1 Glob 145 non-null float64 2 NHem 145 non-null float64 3 SHem 145 non-null float64 4 24N-90N 145 non-null float64 5 24S-24N 145 non-null float64 6 90S-24S 145 non-null float64 7 64N-90N 145 non-null float64 8 44N-64N 145 non-null float64 9 24N-44N 145 non-null float64 10 EQU-24N 145 non-null float64 11 24S-EQU 145 non-null float64 12 44S-24S 145 non-null float64 13 64S-44S 145 non-null float64 14 90S-64S 145 non-null float64 dtypes: float64(14), int64(1) memory usage: 17.1 KB None
OWID¶
#import
owid_co2=pd.read_csv('/content/drive/MyDrive/datascientest_MAI2025/MAI25_CDA_TEMP-TERRESTRE/Livrables/Donnees/GitHub/owid-co2-data.csv')
#shape
print("fichier:'owid-co2-data.csv'")
print(f"le dataframe owid_co2 se compose de {owid_co2.shape[0]} lignes et de {owid_co2.shape[1]} colonnes")
print('\n')
print(owid_co2.info())
fichier:'owid-co2-data.csv' le dataframe owid_co2 se compose de 50191 lignes et de 79 colonnes <class 'pandas.core.frame.DataFrame'> RangeIndex: 50191 entries, 0 to 50190 Data columns (total 79 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 country 50191 non-null object 1 year 50191 non-null int64 2 iso_code 42262 non-null object 3 population 41019 non-null float64 4 gdp 15251 non-null float64 5 cement_co2 28863 non-null float64 6 cement_co2_per_capita 25358 non-null float64 7 co2 29137 non-null float64 8 co2_growth_abs 26981 non-null float64 9 co2_growth_prct 26002 non-null float64 10 co2_including_luc 23585 non-null float64 11 co2_including_luc_growth_abs 23285 non-null float64 12 co2_including_luc_growth_prct 23285 non-null float64 13 co2_including_luc_per_capita 23495 non-null float64 14 co2_including_luc_per_gdp 16790 non-null float64 15 co2_including_luc_per_unit_energy 9701 non-null float64 16 co2_per_capita 26182 non-null float64 17 co2_per_gdp 17528 non-null float64 18 co2_per_unit_energy 10350 non-null float64 19 coal_co2 21755 non-null float64 20 coal_co2_per_capita 21050 non-null float64 21 consumption_co2 4866 non-null float64 22 consumption_co2_per_capita 4502 non-null float64 23 consumption_co2_per_gdp 4444 non-null float64 24 cumulative_cement_co2 28841 non-null float64 25 cumulative_co2 27328 non-null float64 26 cumulative_co2_including_luc 23585 non-null float64 27 cumulative_coal_co2 21755 non-null float64 28 cumulative_flaring_co2 15891 non-null float64 29 cumulative_gas_co2 18014 non-null float64 30 cumulative_luc_co2 37236 non-null float64 31 cumulative_oil_co2 25217 non-null float64 32 cumulative_other_co2 3202 non-null float64 33 energy_per_capita 10109 non-null float64 34 energy_per_gdp 7696 non-null float64 35 flaring_co2 15952 non-null float64 36 flaring_co2_per_capita 14694 non-null float64 37 gas_co2 18014 non-null float64 38 gas_co2_per_capita 17292 non-null float64 39 ghg_excluding_lucf_per_capita 35639 non-null float64 40 ghg_per_capita 35813 non-null float64 41 land_use_change_co2 37236 non-null float64 42 land_use_change_co2_per_capita 36434 non-null float64 43 methane 37410 non-null float64 44 methane_per_capita 35813 non-null float64 45 nitrous_oxide 38280 non-null float64 46 nitrous_oxide_per_capita 36320 non-null float64 47 oil_co2 25218 non-null float64 48 oil_co2_per_capita 24436 non-null float64 49 other_co2_per_capita 2474 non-null float64 50 other_industry_co2 3202 non-null float64 51 primary_energy_consumption 10151 non-null float64 52 share_global_cement_co2 21960 non-null float64 53 share_global_co2 27328 non-null float64 54 share_global_co2_including_luc 23585 non-null float64 55 share_global_coal_co2 21755 non-null float64 56 share_global_cumulative_cement_co2 21960 non-null float64 57 share_global_cumulative_co2 27328 non-null float64 58 share_global_cumulative_co2_including_luc 23585 non-null float64 59 share_global_cumulative_coal_co2 21755 non-null float64 60 share_global_cumulative_flaring_co2 10869 non-null float64 61 share_global_cumulative_gas_co2 15034 non-null float64 62 share_global_cumulative_luc_co2 37236 non-null float64 63 share_global_cumulative_oil_co2 23592 non-null float64 64 share_global_cumulative_other_co2 2108 non-null float64 65 share_global_flaring_co2 10869 non-null float64 66 share_global_gas_co2 15034 non-null float64 67 share_global_luc_co2 37236 non-null float64 68 share_global_oil_co2 23592 non-null float64 69 share_global_other_co2 2108 non-null float64 70 share_of_temperature_change_from_ghg 41001 non-null float64 71 temperature_change_from_ch4 38060 non-null float64 72 temperature_change_from_co2 41001 non-null float64 73 temperature_change_from_ghg 41001 non-null float64 74 temperature_change_from_n2o 38060 non-null float64 75 total_ghg 37410 non-null float64 76 total_ghg_excluding_lucf 37236 non-null float64 77 trade_co2 4535 non-null float64 78 trade_co2_share 4535 non-null float64 dtypes: float64(76), int64(1), object(2) memory usage: 30.3+ MB None
Cyclones¶
gbl_cy=pd.read_csv('/content/drive/MyDrive/datascientest_MAI2025/MAI25_CDA_TEMP-TERRESTRE/Livrables/Donnees/IBTrACS/ibtracs.ALL.list.v04r01.csv',low_memory=False)
#shape
print('fichier: ibtracs.ALL.list.v04r01.csv')
print(f"le dataframe gbl_cy se compose de {gbl_cy.shape[0]} lignes et de {gbl_cy.shape[1]} colonnes")
print('\n')
print(gbl_cy.info())
fichier: ibtracs.ALL.list.v04r01.csv le dataframe gbl_cy se compose de 721938 lignes et de 174 colonnes <class 'pandas.core.frame.DataFrame'> RangeIndex: 721938 entries, 0 to 721937 Columns: 174 entries, SID to STORM_DIR dtypes: int64(1), object(173) memory usage: 958.4+ MB None
PROCESSING¶
GISTEMP¶
Harmonisation des formats¶
Dans les datasets du GISTEMP, global, hémisphères nord et sud, en cas d'absence de valeurs, les données sont figurées par la chaîne de caractères suivante : "***".
La présence de cette chaîne de caractères impacte le type de données, en effet les variables concernées sont considérées comme object et non comme float. De plus, elles ne sont pas reconnues comme NULL. Aussi, la première étape a été de convertir les variables object en float64 pour faciliter les calculs et les analyses, à l’aide de la méthode to_numeric de pandas afin. L'appel à cette méthode permet dans un même temps de traiter les chaînes de caractères problématiques. En effet, les erreurs, des données qui ne sont pas reconnues comme des float sont converties en NaN.
le dataframe Zone annual comporte déjà uniquement des float, pas besoin de convertir le type de données
Pour éviter de répéter la même séquence de code, il est possible de définir des fonctions.
#Compter et localiser les occurrences de '***' dans chaque colonne**
def sum_of_empty_values (df,name):
occurrences = (df =='***').sum()
print('Avant conversion, le dataframe',name,'contient', occurrences.sum(), 'valeurs non exploitables ("***")')
def empty_values (df):
df_empty=df.loc[(df =='***').any(axis=1)]
print('Lignes concernées')
print(df_empty)
return df_empty
#Conversion des object en float
def object_to_float(df):
for col in df.select_dtypes(include=['object']).columns:
df[col] = pd.to_numeric(df[col], errors='coerce')
print('Après conversion, le dataframe contient', (df.isna().sum()).sum(), 'Nan')
return df
#Combinaison pour enchaîner les opérations
def all_processing(df,name):
print("DATAFRAME:",name)
print('\n')
sum_of_empty_values(df, name)
df_empty=empty_values(df)
print('\n')
object_to_float(df)
print('\n')
df.info()
Pour éviter les saisies répétitives, les dataframes concernés sont réunies dans une liste, ainsi les traitements peuvent être appliqués en seule fois à l'aide d'une boucle for
list_of_df={'gbl_loti':gbl_loti, 'nh_loti':nh_loti,'sh_loti':sh_loti}
for name,df in list_of_df.items():
print('='*40)
all_processing(df,name)
print('\n'*2)
========================================
DATAFRAME: gbl_loti
Avant conversion, le dataframe gbl_loti contient 11 valeurs non exploitables ("***")
Lignes concernées
Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov \
0 1880 -0.18 -0.24 -0.09 -0.16 -0.10 -0.21 -0.18 -.10 -.14 -.23 -.22
145 2025 1.37 1.26 1.36 1.23 1.07 1.04 1.03 *** *** *** ***
Dec J-D D-N DJF MAM JJA SON
0 -.17 -.17 *** *** -0.12 -.16 -.20
145 *** *** *** 1.30 1.22 *** ***
Après conversion, le dataframe contient 11 Nan
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 146 entries, 0 to 145
Data columns (total 19 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Year 146 non-null int64
1 Jan 146 non-null float64
2 Feb 146 non-null float64
3 Mar 146 non-null float64
4 Apr 146 non-null float64
5 May 146 non-null float64
6 Jun 146 non-null float64
7 Jul 146 non-null float64
8 Aug 145 non-null float64
9 Sep 145 non-null float64
10 Oct 145 non-null float64
11 Nov 145 non-null float64
12 Dec 145 non-null float64
13 J-D 145 non-null float64
14 D-N 144 non-null float64
15 DJF 145 non-null float64
16 MAM 146 non-null float64
17 JJA 145 non-null float64
18 SON 145 non-null float64
dtypes: float64(18), int64(1)
memory usage: 21.8 KB
========================================
DATAFRAME: nh_loti
Avant conversion, le dataframe nh_loti contient 12 valeurs non exploitables ("***")
Lignes concernées
Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov \
0 1880 -0.37 -0.52 -0.24 -0.31 -0.07 -0.17 -.20 -.28 -.25 -.33 -.44
145 2025 1.83 1.63 1.82 1.57 1.20 1.17 *** *** *** *** ***
Dec J-D D-N DJF MAM JJA SON
0 -.41 -.30 *** *** -0.21 -.22 -.34
145 *** *** *** 1.72 1.53 *** ***
Après conversion, le dataframe contient 12 Nan
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 146 entries, 0 to 145
Data columns (total 19 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Year 146 non-null int64
1 Jan 146 non-null float64
2 Feb 146 non-null float64
3 Mar 146 non-null float64
4 Apr 146 non-null float64
5 May 146 non-null float64
6 Jun 146 non-null float64
7 Jul 145 non-null float64
8 Aug 145 non-null float64
9 Sep 145 non-null float64
10 Oct 145 non-null float64
11 Nov 145 non-null float64
12 Dec 145 non-null float64
13 J-D 145 non-null float64
14 D-N 144 non-null float64
15 DJF 145 non-null float64
16 MAM 146 non-null float64
17 JJA 145 non-null float64
18 SON 145 non-null float64
dtypes: float64(18), int64(1)
memory usage: 21.8 KB
========================================
DATAFRAME: sh_loti
Avant conversion, le dataframe sh_loti contient 12 valeurs non exploitables ("***")
Lignes concernées
Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec \
0 1880 0.0 0.04 0.06 -0.01 -0.12 -0.24 -.16 .07 -.04 -.14 .00 .06
145 2025 0.9 0.89 0.88 0.88 0.94 0.89 *** *** *** *** *** ***
J-D D-N DJF MAM JJA SON
0 -.04 *** *** -0.02 -.11 -.06
145 *** *** .88 0.90 *** ***
Après conversion, le dataframe contient 12 Nan
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 146 entries, 0 to 145
Data columns (total 19 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Year 146 non-null int64
1 Jan 146 non-null float64
2 Feb 146 non-null float64
3 Mar 146 non-null float64
4 Apr 146 non-null float64
5 May 146 non-null float64
6 Jun 146 non-null float64
7 Jul 145 non-null float64
8 Aug 145 non-null float64
9 Sep 145 non-null float64
10 Oct 145 non-null float64
11 Nov 145 non-null float64
12 Dec 145 non-null float64
13 J-D 145 non-null float64
14 D-N 144 non-null float64
15 DJF 145 non-null float64
16 MAM 146 non-null float64
17 JJA 145 non-null float64
18 SON 145 non-null float64
dtypes: float64(18), int64(1)
memory usage: 21.8 KB
Le dataframe des zones annuelles considère une colonne par zone, elles sont transposées en une seule et unique colonne zone. Par ailleurs global, NHem, et SHem étant abordés dans les autres fichiers, ces variables sont supprimées du dataframe. Il en est de même pour les zones qui se recoupent
za_loti_zonly=za_loti[['Year','64N-90N', '44N-64N', '24N-44N', 'EQU-24N', '24S-EQU', '44S-24S',
'64S-44S', '90S-64S']]
za_loti_reversed = za_loti_zonly.melt(
id_vars=['Year'],
var_name='zone',
value_name='temperature_anomaly',
ignore_index=True
).rename(columns={'Year': 'year'})
za_loti_reversed.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1160 entries, 0 to 1159 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 year 1160 non-null int64 1 zone 1160 non-null object 2 temperature_anomaly 1160 non-null float64 dtypes: float64(1), int64(1), object(1) memory usage: 27.3+ KB
Traitement des NaN¶
Les NaN représentent un pourcentage très faible de données et concernent les mois manquant de l’année en cours, ainsi que les moyennes basées sur l’année précédant la période de référence. Le but de l’analyse étant de modéliser la tendance que suit le réchauffement climatique, la suppression de ces données ne l’impacte pas. Aussi, il a été décidé de supprimer les lignes correspondantes des différents dataframes.
gbl_loti=gbl_loti.dropna(axis=0,how='any')
nh_loti=nh_loti.dropna(axis=0,how='any')
sh_loti=sh_loti.dropna(axis=0,how='any')
print('Après suppression')
print('Gobal:',(gbl_loti.isna().sum()).sum(), 'Nan')
print('Hémistphère nord:',(nh_loti.isna().sum()).sum(), 'Nan')
print('Hémisphère Sud:',(sh_loti.isna().sum()).sum(), 'Nan')
print('-'*3)
print('Zones géographiques:',(za_loti.isna().sum()).sum(), 'Nan')
Après suppression Gobal: 0 Nan Hémistphère nord: 0 Nan Hémisphère Sud: 0 Nan --- Zones géographiques: 0 Nan
OWID¶
Pour avoir des échantillons comparables, il est nécessaire d'opérer quelques transformations du dataset:
- la suppression des variables non utilisées,
- la suppression des années non comprises dans les données de la NASA soit avant 1850.
- filtrer sur les continents, pour reconstituer plus facilement les hémisphères
- joindre les dataframes des emissions de gaz à effet et de serre et des anomalies de température
Filtrage des données¶
La colonne nommée country contient réalité plus que des pays, on observe la présence de zone économique comme l'Union Européenne, mais également les continents. Seules les lignes concernant les continents sont retenues pour reconstituer les hémisphères.
#Création d'un nouveau datafame contenant les colonnes pertinentes pour l'étude et renommage de la colonne country
owid_co2_filter=owid_co2[['country','year','co2','co2_including_luc', 'methane','nitrous_oxide','total_ghg','population']].rename(columns={'country':'continent'})
#Une liste des noms de continents est consituée pour pouvoir facilement filter les données d'émissions de gaz à effets de serre
#Les dates non étudiées par les données du GISTEMP sont inclues dans ce même filte
continent=['Africa','Asia','Europe','North America','Oceania','South America']
owid_co2_study=owid_co2_filter[(owid_co2_filter['year']>=1880)&(owid_co2_filter['year']<=2024)&owid_co2_filter['continent'].isin(continent)].reset_index(drop=True)
print("Dataframe après suppression des variables non pertinentes et filtrage sur les dates")
print('\n')
print(owid_co2_study.info())
Dataframe après suppression des variables non pertinentes et filtrage sur les dates <class 'pandas.core.frame.DataFrame'> RangeIndex: 864 entries, 0 to 863 Data columns (total 8 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 continent 864 non-null object 1 year 864 non-null int64 2 co2 860 non-null float64 3 co2_including_luc 860 non-null float64 4 methane 864 non-null float64 5 nitrous_oxide 864 non-null float64 6 total_ghg 864 non-null float64 7 population 864 non-null float64 dtypes: float64(6), int64(1), object(1) memory usage: 54.1+ KB None
Traitement des Nan¶
Les nulls sont supprimés du jeu de données, en raison de leur faible nombre et du fait qu'ils ne concernent qu'un seul continent pour les quatre premières années ne compromet pas l'analyse
print("Lignes contenant des valeurs nulles")
print(owid_co2_study[owid_co2_study.isna().any(axis=1)])
Lignes contenant des valeurs nulles
continent year co2 co2_including_luc methane nitrous_oxide total_ghg \
0 Africa 1880 NaN NaN 88.414 19.343 219.247
1 Africa 1881 NaN NaN 89.115 19.563 225.336
2 Africa 1882 NaN NaN 89.819 19.750 257.469
3 Africa 1883 NaN NaN 90.527 19.910 244.002
population
0 128194527.0
1 128863890.0
2 129548955.0
3 130249836.0
#Suppression des lignes contenant des NaN
owid_co2_clean=owid_co2_study.dropna(axis=0,how='any').reset_index(drop=True)
#Résultat du dataframe nettoyé
print("Dataframe nettoyé")
owid_co2_clean.info()
Dataframe nettoyé <class 'pandas.core.frame.DataFrame'> RangeIndex: 860 entries, 0 to 859 Data columns (total 8 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 continent 860 non-null object 1 year 860 non-null int64 2 co2 860 non-null float64 3 co2_including_luc 860 non-null float64 4 methane 860 non-null float64 5 nitrous_oxide 860 non-null float64 6 total_ghg 860 non-null float64 7 population 860 non-null float64 dtypes: float64(6), int64(1), object(1) memory usage: 53.9+ KB
Attribution d'un hémisphère pour chaque contient¶
Il faut désormais attribuer un hémisphère au continent 'NHem', 'SHem', on peut ajouter une nouvelle colonne en faisant des correspondances. Pour cela un dictionnaire de mappping associé à la méthode map d'associer le bon continent au bon hémisphère. La notation Shemet Nhememployée dans les données GISTEMP sont appliquées pour faciliter les rapprochements futurs.
hemisphere_dict= {
'Africa': 'SHem',
'Oceania': 'SHem',
'South America': 'SHem',
'Asia': 'NHem',
'Europe': 'NHem',
'North America': 'NHem'
}
owid_co2_clean['hemisphere'] = owid_co2_clean['continent'].map(hemisphere_dict)
print("Dataframe après attribution d'un hémisphère pour chaque continent, exécutée grâce à la méthode `.map()`")
print("\n")
print(owid_co2_clean.info())
Dataframe après attribution d'un hémisphère pour chaque continent, exécutée grâce à la méthode `.map()` <class 'pandas.core.frame.DataFrame'> RangeIndex: 860 entries, 0 to 859 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 continent 860 non-null object 1 year 860 non-null int64 2 co2 860 non-null float64 3 co2_including_luc 860 non-null float64 4 methane 860 non-null float64 5 nitrous_oxide 860 non-null float64 6 total_ghg 860 non-null float64 7 population 860 non-null float64 8 hemisphere 860 non-null object dtypes: float64(6), int64(1), object(2) memory usage: 60.6+ KB None
print('les moyennes annuelles par hémisphère permettront de les confronter aux anomalies de températures relevées dans ces deux zones géographiques')
co2_annual_mean= owid_co2_clean.groupby(['year', 'hemisphere'])[['co2', 'co2_including_luc','methane','nitrous_oxide','total_ghg','population']].mean()
print(co2_annual_mean.head())
les moyennes annuelles par hémisphère permettront de les confronter aux anomalies de températures relevées dans ces deux zones géographiques
co2 co2_including_luc methane nitrous_oxide \
year hemisphere
1880 NHem 283.842667 1362.452667 458.787667 67.737000
SHem 3.263000 150.229500 39.689000 12.566500
1881 NHem 293.524333 1339.009333 463.723000 68.478333
SHem 3.696500 162.643000 40.736500 12.711000
1882 NHem 309.926000 1391.886667 468.713000 69.118333
total_ghg population
year hemisphere
1880 NHem 1794.656000 4.188681e+08
SHem 212.389000 1.600544e+07
1881 NHem 1799.069333 4.215456e+08
SHem 226.157500 1.630267e+07
1882 NHem 1865.705333 4.244031e+08
Cyclones¶
Nettoyage et harmonisation des formats¶
Les données IBTrACS contiennent un grand nombre de variables qui ne sont pas pertinentes pour cette étude, aussi elles sont supprimées du dataframe. La colonne SEASONest renommée en year, un nom plus explicite, pour faciliter les rapprochements avec les données du GISTEMP.
La deuxième ligne du fichier contient l'unité employée pour certaine colonne, elle est suprimée, car inutile dans le contexte de l'étude et génère du bruit pour le type de données.
La colonne LAT est convertie en float pour faciliter les manipulations. Le fichier suit le parcours d'un cyclone, or dans le cadre de cette étude, cherchant à mettre en relation les anomalies de température et la fréquence des cyclones, cette information n'est pas utile. En revanche, la lattitude moyenne du cyclone est retenue afin d'en connaître une localisation approximative dans le but de le situer dans l'une des zones climatiques définies dans les données du GISTEMP.
#Suppression des variables et de la deuxième ligne
cy_filtered=gbl_cy[['SID','SEASON','LAT','ISO_TIME','NATURE']].copy()
cy_filtered = cy_filtered.rename(columns={'SEASON': 'year'})
cy_filtered = cy_filtered.drop(index=0).reset_index(drop=True)
print('Après suppression des variables et de la deuxième ligne')
print('\n')
print(cy_filtered.head(3))
cy_filtered.info()
Après suppression des variables et de la deuxième ligne
SID year LAT ISO_TIME NATURE
0 1842298N11080 1842 10.9 1842-10-25 03:00:00 NR
1 1842298N11080 1842 10.9 1842-10-25 06:00:00 NR
2 1842298N11080 1842 10.8 1842-10-25 09:00:00 NR
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 721937 entries, 0 to 721936
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 SID 721937 non-null object
1 year 721937 non-null object
2 LAT 721937 non-null object
3 ISO_TIME 721937 non-null object
4 NATURE 721937 non-null object
dtypes: object(5)
memory usage: 27.5+ MB
#Modification des types de la colonne LAT
cy_filtered['LAT']=cy_filtered['LAT'].astype('float')
cy_filtered['year']=cy_filtered['year'].astype('int')
print('Dataframe après conversion des colonnes `LAT` et `year`')
print('\n')
print(cy_filtered.info())
Dataframe après conversion des colonnes `LAT` et `year` <class 'pandas.core.frame.DataFrame'> RangeIndex: 721937 entries, 0 to 721936 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 SID 721937 non-null object 1 year 721937 non-null int64 2 LAT 721937 non-null float64 3 ISO_TIME 721937 non-null object 4 NATURE 721937 non-null object dtypes: float64(1), int64(1), object(3) memory usage: 27.5+ MB None
Regroupement et filtrage des données¶
La trajectoire des cyclones dans le cadre de cette analyse n'est pas prise en compte à la faveur de la fréquence. Aussi seule la première latitude enregistrée par cyclone est retenue. L'évolution des cyclones étant enregistrée de manière chronologique, la variable start_LAT est donc crée est sera considérée comme le point le plus proche de la source du cyclone.
#Regroupement selon la lattitude moyenne
cy_grp=cy_filtered.groupby(['SID','year','NATURE'])['LAT'].first().rename('start_LAT').reset_index()
cy_study=cy_grp[(cy_grp['year']>=1880)&(cy_grp['year']<=2024)].reset_index(drop=True)
print('Dataframe après filtrage')
print('\n')
print(cy_study.head())
print('\n')
print('='*60)
print('\n')
print(cy_study.info())
Dataframe après filtrage
SID year NATURE start_LAT
0 1879344S16059 1880 TS -16.4
1 1879345S15060 1880 NR -15.3
2 1879345S16054 1880 TS -15.9
3 1879345S16059 1880 NR -15.7
4 1879355S15054 1880 NR -15.2
============================================================
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 21959 entries, 0 to 21958
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 SID 21959 non-null object
1 year 21959 non-null int64
2 NATURE 21959 non-null object
3 start_LAT 21959 non-null float64
dtypes: float64(1), int64(1), object(2)
memory usage: 686.3+ KB
None
Attribution d'une zone climatique¶
Les lattitudes moyennes obtenues sont rapprochées des zones climatiques déclarées dans les données GISTEMP afin de pouvoir mesurer les corrélations entre les deux phénomènes à l'échelle planétaire mais également sur des zones plus réduites. Pour cela, la méthode .cut()est employée pour situer une lattitude dans un intervalle défini.
#Création des intervalles de lattitudes
bins=[-90,-64,-44,-24,0,24,44,64,90]
labels=['90S-64S','64S-44S','44S-24S','24S-EQU','EQU-24N','24N-44N','44N-64N','64N-90N']
cy_study['zone'] = pd.cut(
cy_study['start_LAT'],
bins=bins,
labels=labels,
right=False
)
cy_study['zone']=cy_study['zone'].astype('object')
#Attribution d'un hémisphère
bins=[-90,0,90]
labels=['SHem','NHem']
cy_study['hemisphere'] = pd.cut(
cy_study['start_LAT'],
bins=bins,
labels=labels,
right=False
)
cy_study['hemisphere']=cy_study['hemisphere'].astype('object')
print('Dataframe final')
print('\n')
separator = pd.DataFrame([['...'] * len(cy_study.columns)], columns=cy_study.columns)
print(pd.concat([cy_study.head(3), separator, cy_study.tail(3)], ignore_index=False))
print('\n')
print('='*60)
print('\n')
print(cy_study.info())
Dataframe final
SID year NATURE start_LAT zone hemisphere
0 1879344S16059 1880 TS -16.4 24S-EQU SHem
1 1879345S15060 1880 NR -15.3 24S-EQU SHem
2 1879345S16054 1880 TS -15.9 24S-EQU SHem
0 ... ... ... ... ... ...
21956 2024356N14084 2024 TS 13.7 EQU-24N NHem
21957 2024357N10115 2024 MX 10.3 EQU-24N NHem
21958 2024357N10115 2024 TS 10.1 EQU-24N NHem
============================================================
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 21959 entries, 0 to 21958
Data columns (total 6 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 SID 21959 non-null object
1 year 21959 non-null int64
2 NATURE 21959 non-null object
3 start_LAT 21959 non-null float64
4 zone 21959 non-null object
5 hemisphere 21959 non-null object
dtypes: float64(1), int64(1), object(4)
memory usage: 1.0+ MB
None
DISTRIBUTION VARIABLES¶
Anomalies de températures¶
Les moyennes annuelles au global et pour chaque hémisphère suivent une distribution asymétrique, les anomalies négatives sont plus nombreuses. Cela signifie qu’au global, sans notion de temporalité, l’on constate un nombre plus important d'années “froides” , entre 0 et -0,5°C, que d’années “chaudes”, par rapport à la période de référence. On constate également que les anomalies positives présentent un écart plus important à la période de référence, jusqu'à +1,5°C quasiment trois fois plus important que celui des anomalies négatives. La comparaison des deux hémisphères révèlent que le nord est exposé à une plus importante variation des anomalies.
Les boxplots révèlent la présence de valeurs aberrantes supérieures à des anomalies de +1°C qui concernent toutes l'hémisphère nord. Au global, la médiane se situe aux alentours de 0°C. Les deuxième et troisième quartiles confirment l’intervalle plus important concernés par les anomalies positives. L’intégralité des valeurs aberrantes se retrouvent au niveau de l’hémisphère nord, et elles concernent des anomalies positives. Leur présence contrebalance l’équilibre observé entre les premier et deuxième quartile. Cela peut suggérer des périodes particulièrement chaudes dans cette zone de la planète. Les moustaches, indiquant les valeurs minimales et maximales, confirment que le nord est exposé à des variations plus importantes que le sud.
Les courbes montrent une augmentation continue du réchauffement des températures relevées à la surface des sols. Les valeurs identifiées comme aberrantes dans les boxplots concernent l’année 2024, ce qui suggérerait une accélération plus marquée. Dans l’hémisphère nord, l’augmentation est plus importante à partir des années 1950 et s’intensifie encore à partir de 1975. A l’inverse, dans l’hémisphère sud, on constate comme un plateau jusqu’au début des années 1930, suivi de quelques années particulièrement chaudes. Par la suite, la courbe suit une trajectoire plutôt linéaire.
Les trois types de graphiques tendent à démontrer une augmentation globale des températures relevées au sol. Cependant il faut souligner une évolution différente entre les deux hémisphères. Celui du nord connait un réchauffement plus important et sur une période plus longue par rapport à celui du sud. L'évolution des anomalies de températures relevées sur les différentes zones climatiques permet d'affiner l'analyse.
La majeure partie des zones climatiques suivent une trajectoire similaire. L'augmentation des températures est constante, depuis la fin des années 1910. Les cercles articque et antarticque sont les zones qui connaissent les plus grandes variations de température. Il faut souligner pour le premier, qu'il est la zone qui s'est le plus réchauffée et l'augmentation des témpératures s'est considérablement accrue depuis la fin des années 1990. Il affiche aujourd'hui une moyenne supérieure à +2,5°C par rapport à la période de référence. Cela se traduit par une accélaration de la fonte des glaces et donc une montée des eaux.
Moyennes annuelles J-D¶
fig, axes = plt.subplots(3, 3, figsize=(14, 10))
plt.suptitle('Distribution de la moyenne annuelle',fontweight='bold',x=0.15)
# Echelle du monde
sns.histplot(gbl_loti['J-D'], kde=True,ax=axes[0, 0])
axes[0, 0].set_title('Distribution des anomalies (Global)', loc='left')
sns.boxplot(x=gbl_loti['J-D'], ax=axes[0,1])
axes[0, 1].set_title('Répartition des anomalies (Global)', loc='left')
sns.regplot(x='Year', y='J-D', data=gbl_loti,
lowess=True, line_kws={'color': 'red'}, ax=axes[0, 2])
axes[0, 2].set_title('Évolution des anomalies (Global)', loc='left')
# Hémisphère nord
sns.histplot(nh_loti['J-D'], kde=True, ax=axes[1, 0])
axes[1, 0].set_title('Distribution des anomalies (NH)', loc='left')
sns.boxplot(x=nh_loti['J-D'], ax=axes[1,1])
axes[1, 1].set_title('Répartition des anomalies (NH)', loc='left')
sns.regplot(x='Year', y='J-D', data=nh_loti,
lowess=True, line_kws={'color': 'red'}, ax=axes[1,2])
axes[1, 2].set_title('Évolution des anomalies (NH)', loc='left')
# Hémisphère sud
sns.histplot(sh_loti['J-D'], kde=True, ax=axes[2, 0])
axes[2, 0].set_title('Distribution des anomalies (SH)', loc='left')
sns.boxplot(x=sh_loti['J-D'], ax=axes[2,1])
axes[2, 1].set_title('Répartition des anomalies (SH)', loc='left')
sns.regplot(x='Year', y='J-D', data=sh_loti,
lowess=True, line_kws={'color': 'red'}, ax=axes[2, 2])
axes[2, 2].set_title('Évolution des anomalies (SH)', loc='left')
plt.tight_layout()
plt.show()
Moyennes annuelles par zone climatique¶
#Pour rendre le graphique plus lisible, une moyenne glissante sur 10 années est utilisée
window=10
za_loti_reversed['temp_anomalies'] = za_loti_reversed['temperature_anomaly'].rolling(window).mean()
plt.figure(figsize=(15, 6))
sns.lineplot(data=za_loti_reversed, x='year', y='temp_anomalies', hue='zone', palette='muted')
plt.suptitle('Evolution des anomalies de températures par zone', fontweight='bold',x=0.323)
plt.title('Moyenne glissante sur 10 ans',loc='left',pad=10, fontsize=10)
plt.axhline(y=0, color='black', linestyle='--', linewidth=1)
plt.legend(loc='upper left')
plt.show();
Cyclones¶
Il est à noter que la précision avec laquelle les cyclones sont pistés s'est considérablement améloriée avec l'apport de la surveillance sattelitaire à partir des années 1960. La période après 1979 est considérée comme le début de l'ère moderne de la surveillance où la couverture est quasi globale. Auparavant la qualité et la complétude des données sont inégales. Cela a pour effet d'augmenter artificiellement le nombre de cyclones, car un même phénomène a pu être comptabilisé en plusieurs évènements.
La distribution par nature de cyclone révèle la prédominance des systèmes tropicaux (TS) ce qui peut trouver une explication dans la nature même du jeu de données, car le projet IBTrACS est l'archive mondiale pour les cyclones tropicaux. Les natures NR (non renseignée) et MX (mixte) sont difficilement exploitables car ne définissent pas les cyclones mais trahissent seulement l'impossibilité de définir le cyclone. Pour cette dernière, le boxplot fait apparaitre une concentration plus forte pour les périodes les plus récentes en raison notamment, de la mutltiplication des sources primaires utilisées qui chacune emploie une taxonomie difficilement réconciliable.
La part plus faible des disturbances (DS) et des systèmes subtropicaux (SS) trouvent également une explication dans les données, car ils n'ont pas toujours étaient inclus dans le périmètre de surveillance. Cela est illustré en partie par les valeurs qui pourraient être considérées comme abérrantes.
Malgré la potentielle imprécision des données pour les années les plus anciennes, l'augementation du nombre de cyclones par an est nettement observable notamment à partir des années 1950. On observe égalemnet un premier pic au cours des années 1970 et un second au début des années 2020.
Étant donné que les cyclones tropicaux sont les plus nombreux, il est normal que la bande latitudinale entre l'équateur et le tropique du Cancer soit la zone comptant le plus de cyclones. Plus l'on s'éloigne de l'équateur, plus le nombre de cyclones diminue, en raison d'une présence plus prononcée des eaux froides.
Distribution¶
fig, axes = plt.subplots(2,2, figsize=(15, 10))
#Répartition par type
sns.countplot(x='NATURE', data=cy_study, ax=axes[0,0], hue='NATURE', palette='Paired')
axes[0,0].set_title('Distribution par nature',loc='left')
plt.xticks(rotation=45)
sns.boxplot(data=cy_grp,x='year', y='NATURE',hue='NATURE',ax=axes[0,1],palette='Paired')
axes[0,1].set_title('Boxplot',loc='left')
#Répartition par année
sns.histplot(cy_study['year'], ax=axes[1,0], bins=50, alpha=0.7, color='orange' )
axes[1,0].set_title('Distribution par année', loc='left')
#Répartition par zone
sns.countplot(x='zone', data=cy_study, ax=axes[1,1], hue='zone', palette='muted')
axes[1,1].set_title('Distribution par zone',loc='left')
plt.xticks(rotation=45)
plt.tight_layout()
Évolution¶
#Création d'un dataframe pour compter le nombre de cyclone par an et par nature
cy_grp=cy_study.groupby(['year','NATURE','zone','hemisphere'])['SID'].count().reset_index()
plt.figure(figsize=(15, 6))
sns.histplot(data=cy_grp, x='year', weights='SID', hue='zone', multiple='stack',discrete=True, palette='muted', alpha=0.6)
plt.title("Évolution du nombre de cyclones par zone climatique", loc='left', fontweight='bold')
plt.show()
Émissions de GES¶
Pour observer la distribution des émissions de GES, un dataframe où sont transposées en une seule colonne tous les types de gaz est créé pour faciliter la création des visualisations.
ghg_transpose= owid_co2_clean.melt(
id_vars=['year','continent'],
value_vars=(['co2_including_luc', 'methane','nitrous_oxide']),
var_name='GHG',
value_name='emission',
ignore_index=True
)
print(ghg_transpose.info())
<class 'pandas.core.frame.DataFrame'> RangeIndex: 2580 entries, 0 to 2579 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 year 2580 non-null int64 1 continent 2580 non-null object 2 GHG 2580 non-null object 3 emission 2580 non-null float64 dtypes: float64(1), int64(1), object(2) memory usage: 80.8+ KB None
La distribution des émissions de GES par continent montre que l'Asie domine largement les émissions, suivie de l'Europe, l'Amérique du Nord, l'Afrique et l'Océanie. Celle par type de gaz révèlent le CO₂ est le principal contributeur aux émissions globales, très loin devant le méthane et le protoxyde d'azone. La régression linéaire des moyennes annuelles depuis 1880, illustre quant à elle une augmentation marquée et quasi exponentielle des émissions totales de GES au fil du temps.
Le détail par continent permet d'observer la trajectoire de chacun. L'Asie présente une croissance spectaculaire et continue. L'Europe montre un pic vers 1980 puis un déclin. L'Afrique et l'Amérique du Nord connaissent des augmentations régulières. L'Océanie et l'Amérique du Sud affichent des fluctuations avec tendance générale à la hausse. Le détail des émissions par type de gaz permet d'observer que quelque soit le type de gaz, le classement par continent reste inchangé avec l'Asie comme le plus important émetteur. À noter que l'Europe a considérablement augmenté ses émissions en protoxyde d'azote, jusqu'à en être le plus important au cours des années 1950-1980. Ce pic est très certainement à mettre en relation avec l'intensification de l'agriculture, potentiellement limitées par l'introduction de politiques environnemntales.
Le graphique en barres empilées montre l'accumulation des trois types de GES depuis 1880. Le CO₂ constitue la majorité écrasante des émissions et sa croissance s'accélère particulièrement à partir de 1950. Le méthane et le protoxyde d'azote forment des portions mineures mais croissantes. L'augmentation globale est très nette après le milieu du XXe siècle.
Distribution¶
fig, axes = plt.subplots(1, 3, figsize=(17, 5))
plt.suptitle("Distribution des émissions GHG par continent et type de gaz", fontweight='bold',x=0.3)
#par continent
sns.barplot(
data=ghg_transpose, x="continent", y="emission", errorbar=None, hue="continent",
palette='magma', ax=axes[0], alpha=0.7, legend='brief'
)
axes[0].set_xlabel('')
axes[0].set_ylabel('Emissions')
axes[0].set_xticklabels([])
sns.move_legend(axes[0], "upper right")
#par GHG
sns.barplot(
data=ghg_transpose, x="GHG", y="emission", errorbar=None, hue="GHG",
palette='viridis', ax=axes[1], alpha=0.7, legend='brief'
)
axes[1].set_xlabel('')
axes[1].set_ylabel('Emissions')
axes[1].set_xticklabels([])
sns.move_legend(axes[1], "upper right")
#Création d'un dataframe pour isoler et calculer les émissions moyennes de tous les continents
owid_total_gh_mean=owid_co2_clean.groupby('year')['total_ghg'].mean().reset_index()
sns.regplot(x='year', y='total_ghg', data=owid_total_gh_mean,
line_kws={'color': 'red'}, ax=axes[2])
axes[2].set_title('Régression linéaire des moyennes annuelles', loc='left', fontsize='small')
plt.show()
Évolution¶
plt.figure(figsize=(15, 7))
sns.histplot(data=ghg_transpose, x='year', weights='emission', hue='GHG', multiple='stack',discrete=True, palette='viridis')
plt.title("Évolutions des émissions de GHG par type de gaz", loc='left', fontweight='bold')
plt.show()
Émission par continent¶
g = sns.FacetGrid(ghg_transpose, col="continent", col_wrap=3, height=4, sharey=False)
g.map_dataframe(sns.lineplot, x='year', y='emission', hue='GHG', palette='viridis')
g.set_titles("")
g.set_titles(col_template="{col_name}", size=10, fontweight='bold',loc='left')
g.set_axis_labels('Year', 'Emission')
g.add_legend(bbox_to_anchor=(1, 1), loc='upper right')
plt.show()
Émission de gaz¶
g = sns.FacetGrid(ghg_transpose, col="GHG", height=4, sharey=False)
g.map_dataframe(sns.lineplot, x='year', y='emission', hue='continent', palette='magma')
g.set_axis_labels('Year', 'Emission')
g.set_titles("")
g.set_titles(col_template="{col_name}", size=10, fontweight='bold',loc='left')
g.add_legend(bbox_to_anchor=(1, 1), loc='upper right')
plt.show()
CORRÉLATIONS¶
Préparation des données¶
Afin de pouvoir mesurer la ou les corrélations existantes entre les anomalies de température, les émisssions de GES et la fréquence des cyclones, il est nécessaire de réunir les trois jeux de données dans un même dataframe.
Chacun des jeux de données présentant des données temporelles, mais également géographique, ces corrélations pourront être mesurées dans le temps ainsi qu'à l'échèlle des hémisphères. En effet, l'utilisation des zones climatiques définies par bandes lattitudinales n'est pas idoine pour le cas des continents qui recouvrent plusieurs zones.
Concaténation des données GISTEMP¶
Les dataframes des hémisphère Nord et Sud vont être concaténés afin d'obtenir un ensemble global avant de le joindre aux données des émissions de GES. Seule la moyenne annuelle est retenue car les autres jeux de données traitent uniquement les années.
#Ajout d'une colonne hemisphere pour faire la jointure avec les emissions de CO2
#nord
nh_loti_co2=nh_loti[['Year','J-D']].rename(columns={'Year': 'year'})
nh_loti_co2['hemisphere']='NHem'
#sud
sh_loti_co2=sh_loti[['Year','J-D']].rename(columns={'Year': 'year'})
sh_loti_co2['hemisphere']='SHem'
gbl_loti_co2=pd.concat([nh_loti_co2,sh_loti_co2],axis=0)
print(gbl_loti_co2.info())
<class 'pandas.core.frame.DataFrame'> Index: 288 entries, 1 to 144 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 year 288 non-null int64 1 J-D 288 non-null float64 2 hemisphere 288 non-null object dtypes: float64(1), int64(1), object(1) memory usage: 9.0+ KB None
Création du dataframe de corréaltion¶
cy_hemis=cy_grp.groupby(['year','hemisphere'])['SID'].count().reset_index().rename(columns={'SID':'nb_cyclones'})
print('Dataframe du nombre de cyclones par hémisphère')
print('\n')
print(cy_hemis.info())
Dataframe du nombre de cyclones par hémisphère <class 'pandas.core.frame.DataFrame'> RangeIndex: 290 entries, 0 to 289 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 year 290 non-null int64 1 hemisphere 290 non-null object 2 nb_cyclones 290 non-null int64 dtypes: int64(2), object(1) memory usage: 6.9+ KB None
#pour confronter les données, il est nécessaire de les réunir dans un même dataframe
df_temp=pd.merge(co2_annual_mean, gbl_loti_co2, on =['year','hemisphere'], how='inner').rename(columns={'J-D':'temperature_anomaly'})
co2_temp=pd.merge(df_temp,cy_hemis, on=['year', 'hemisphere'], how='left')
print('Dataframe de corrélations')
print(co2_temp.info())
Dataframe de corrélations <class 'pandas.core.frame.DataFrame'> RangeIndex: 286 entries, 0 to 285 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 year 286 non-null int64 1 hemisphere 286 non-null object 2 co2 286 non-null float64 3 co2_including_luc 286 non-null float64 4 methane 286 non-null float64 5 nitrous_oxide 286 non-null float64 6 total_ghg 286 non-null float64 7 population 286 non-null float64 8 temperature_anomaly 286 non-null float64 9 nb_cyclones 286 non-null int64 dtypes: float64(7), int64(2), object(1) memory usage: 22.5+ KB None
#Création de dataframe pour chaque hémisphère pour les visualisations
co2_temp_N=co2_temp[(co2_temp['hemisphere']=='NHem')].copy()
co2_temp_S=co2_temp[(co2_temp['hemisphere']=='SHem')].copy()
#Ajout d'une moyenne glissante de 5 ans pour les visualisations
window=5
co2_temp_N['temp_smooth'] = co2_temp_N['temperature_anomaly'].rolling(window).mean()
co2_temp_N['ghg_smooth']=co2_temp_N['total_ghg'].rolling(window).mean()
co2_temp_N['cy_smooth']=co2_temp_N['nb_cyclones'].rolling(window).mean()
co2_temp_S['temp_smooth'] = co2_temp_S['temperature_anomaly'].rolling(window).mean()
co2_temp_S['ghg_smooth']=co2_temp_S['total_ghg'].rolling(window).mean()
co2_temp_S['cy_smooth']=co2_temp_S['nb_cyclones'].rolling(window).mean()
Graphiques¶
Global¶
#Création d'un dataframe avec les moyennes annuelles pour la visualisation
co2_temp_gbl=co2_temp.groupby(['year'])[['temperature_anomaly','total_ghg','nb_cyclones']].mean().reset_index()
print("Création d'un dataframe avec les moyennes annuelles pour la visualisation, ajout d'une moyenne glissante sur 5 ans")
window=5
co2_temp_gbl['temp_smooth'] = co2_temp_gbl['temperature_anomaly'].rolling(window).mean()
co2_temp_gbl['ghg_smooth']=co2_temp_gbl['total_ghg'].rolling(window).mean()
co2_temp_gbl['cy_smooth']=co2_temp_gbl['nb_cyclones'].rolling(window).mean()
print(co2_temp_gbl.info())
Création d'un dataframe avec les moyennes annuelles pour la visualisation, ajout d'une moyenne glissante sur 5 ans <class 'pandas.core.frame.DataFrame'> RangeIndex: 143 entries, 0 to 142 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 year 143 non-null int64 1 temperature_anomaly 143 non-null float64 2 total_ghg 143 non-null float64 3 nb_cyclones 143 non-null float64 4 temp_smooth 139 non-null float64 5 ghg_smooth 139 non-null float64 6 cy_smooth 139 non-null float64 dtypes: float64(6), int64(1) memory usage: 7.9 KB None
fig, ax1 = plt.subplots(figsize=(12, 6))
#Courbe température
ax1.plot(co2_temp_gbl['year'], co2_temp_gbl['temp_smooth'],
color='#3399ff', label='Anomalie T°',alpha=0.6)
#Courbe co2
ax2 = ax1.twinx()
ax2.plot(co2_temp_gbl['year'], co2_temp_gbl['ghg_smooth'],
color='#003366', ls = '-.', linewidth=2, label='Emissions GES')
#Courbe cyclones
ax3 = ax1.twinx()
ax3.spines['right'].set_position(('outward', 60))
ax3.plot(co2_temp_gbl['year'], co2_temp_gbl['cy_smooth'],
color='green', ls = ':', label='Cyclones ')
# Titre et légende
plt.title('Global: GES, Température, Cyclones',loc='left',fontweight='bold', pad=20)
ax1.set_xlabel('Année')
ax1.set_ylabel('température (°C)')
ax2.set_ylabel('GES (milions de tonnes)')
ax3.set_ylabel('Cyclones (nombre)')
lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
lines3, labels3 = ax3.get_legend_handles_labels()
ax1.legend(lines1 + lines2 + lines3, labels1 + labels2 + labels3, loc='upper left')
# événements
bbox=dict(facecolor='white', alpha=1, edgecolor='none')
ax1.axvline(x=1945, color='grey', alpha=0.3)
ax1.text(1945, ax1.get_ylim()[-1]+0.03, '1945\nFin de la 2nde guerre', color='grey', fontsize=9, alpha=0.7, bbox=bbox)
ax1.axvline(x=1979, color='brown', alpha=0.3)
ax1.text(1979, ax1.get_ylim()[-1]+0.03, '1979\nElection de Margaret Thatcher', color='brown', fontsize=9, alpha=0.7, bbox=bbox)
ax1.axvline(x=2015, color='forestgreen', alpha=0.3)
ax1.text(2015, ax1.get_ylim()[-1]+0.03, '2015\nAccord de Paris', color='forestgreen', fontsize=9, alpha=0.7,bbox=bbox)
plt.grid(alpha=0.3)
fig.tight_layout()
plt.show();
Hémisphère Sud¶
fig, ax1 = plt.subplots(figsize=(12, 6))
#Courbe température
ax1.plot(co2_temp_S['year'], co2_temp_S['temp_smooth'],
color='#3399ff', label='Anomalie T°',alpha=0.6)
#Courbe co2
ax2 = ax1.twinx()
ax2.plot(co2_temp_S['year'], co2_temp_S['ghg_smooth'],
color='#003366', ls = '-.', linewidth=2, label='Emissions GES')
#Courbe cyclones
ax3 = ax1.twinx()
ax3.spines['right'].set_position(('outward', 60))
ax3.plot(co2_temp_S['year'], co2_temp_S['cy_smooth'],
color='green', ls = ':', label='Cyclones ')
# Titre et légende
plt.title('Hémisphère Sud : GES, Température, Cyclones',loc='left',fontweight='bold', pad=20)
ax1.set_xlabel('Année')
ax1.set_ylabel('température (°C)')
ax2.set_ylabel('GES (milions de tonnes)')
ax3.set_ylabel('Cyclones (nombre)')
lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
lines3, labels3 = ax3.get_legend_handles_labels()
ax1.legend(lines1 + lines2 + lines3, labels1 + labels2 + labels3, loc='upper left')
plt.grid(alpha=0.3)
fig.tight_layout()
plt.show();
Hémishpère Nord¶
fig, ax1 = plt.subplots(figsize=(12, 6))
#Courbe température
ax1.plot(co2_temp_N['year'], co2_temp_N['temp_smooth'],
color='#3399ff', label='Anomalie T°',alpha=0.6)
#Courbe co2
ax2 = ax1.twinx()
ax2.plot(co2_temp_N['year'], co2_temp_N['ghg_smooth'],
color='#003366', ls = '-.', linewidth=2, label='Emissions GES')
#Courbe cyclones
ax3 = ax1.twinx()
ax3.spines['right'].set_position(('outward', 60))
ax3.plot(co2_temp_N['year'], co2_temp_N['cy_smooth'],
color='green', ls = ':', label='Cyclones ')
# Titre et légende
plt.title('Hémisphère Nord : GES, Température, Cyclones',loc='left',fontweight='bold', pad=20)
ax1.set_xlabel('Année')
ax1.set_ylabel('température (°C)')
ax2.set_ylabel('GES (milions de tonnes)')
ax3.set_ylabel('Cyclones (nombre)')
lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
lines3, labels3 = ax3.get_legend_handles_labels()
ax1.legend(lines1 + lines2 + lines3, labels1 + labels2 + labels3, loc='upper left')
plt.grid(alpha=0.3)
fig.tight_layout()
plt.show();
Corrélations¶
#corrélation sur l'ensemble des données
corr_gbl=co2_temp[['temperature_anomaly','total_ghg', 'population','nb_cyclones']].corr().round(3)
#corrélation regroupée par hémisphère
corr_par_hemis = co2_temp.groupby('hemisphere')[['temperature_anomaly','total_ghg','population','nb_cyclones']].corr().round(3)
print('GLOBAL')
print('-'*15)
print(corr_gbl)
print('\n')
print('='*80)
print('PAR HEMISPHERE')
print('-'*15)
print(corr_par_hemis)
GLOBAL
---------------
temperature_anomaly total_ghg population nb_cyclones
temperature_anomaly 1.000 0.68 0.661 0.603
total_ghg 0.680 1.00 0.990 0.710
population 0.661 0.99 1.000 0.725
nb_cyclones 0.603 0.71 0.725 1.000
================================================================================
PAR HEMISPHERE
---------------
temperature_anomaly total_ghg population \
hemisphere
NHem temperature_anomaly 1.000 0.887 0.906
total_ghg 0.887 1.000 0.995
population 0.906 0.995 1.000
nb_cyclones 0.517 0.691 0.673
SHem temperature_anomaly 1.000 0.898 0.925
total_ghg 0.898 1.000 0.953
population 0.925 0.953 1.000
nb_cyclones 0.860 0.893 0.878
nb_cyclones
hemisphere
NHem temperature_anomaly 0.517
total_ghg 0.691
population 0.673
nb_cyclones 1.000
SHem temperature_anomaly 0.860
total_ghg 0.893
population 0.878
nb_cyclones 1.000
fig, axes = plt.subplots(1, 3, figsize=(17, 7))
#Global
sns.heatmap(
data=corr_gbl,
annot=True,
cmap='coolwarm',
ax=axes[0],
vmin=0.5, vmax=1,
cbar=False
)
axes[0].set_title("Corrélations global", loc='left', pad=10)
axes[0].set_xticklabels(axes[0].get_xticklabels(), rotation=45)
#NHem
sns.heatmap(
data=corr_par_hemis.xs('NHem', level=0),
annot=True,
cmap='coolwarm',
ax=axes[1],
vmin=0.5, vmax=1,
yticklabels=False,
xticklabels=False,
cbar=False
)
axes[1].set_title("Corrélations pour NHem", loc='left', pad=10)
# Heatmap pour SHem
sns.heatmap(
data=corr_par_hemis.xs('SHem', level=0),
annot=True,
cmap='coolwarm',
ax=axes[2],
vmin=0.5, vmax=1,
yticklabels=False,
xticklabels=False
)
axes[2].set_title("Corrélations pour SHem", loc='left', pad=10)
plt.suptitle("Corrélations émissions de GES, anomalies de température, nombre de cyclones", fontweight='bold',x=0.2)
plt.tight_layout()
plt.show();
CONCLUSIONS¶
Cette étude révèle une relation directe et croissante entre les émissions de gaz à effet de serre, l'augmentation des températures et l'intensité des cyclones. Cependant, cette relation présente une asymétrie marquée entre les deux hémisphères, l'hémisphère Sud montrant une sensibilité climatique nettement supérieure. Principaux constats
- Le lien GES-Température : une relation robuste et universelle À l'échelle mondiale, les émissions totales de GES et les anomalies de température présentent une corrélation forte (r = 0.68), confirmant le lien causal bien établi par la science climatique. Cette corrélation s'intensifie même à l'hémisphère Nord (r = 0.89) et atteint son maximum au Sud (r = 0.90). L'analyse temporelle montre que cette relation s'accélère dramatiquement après 1950, période marquant l'industrialisation intensive et la multiplication des sources d'émissions anthropiques. Le graphique global illustre un doublement de la corrélation apparente après les années 1980, reflet d'une amplification du forçage climatique.
- Les cyclones : un indicateur complexe et différencié Le nombre de cyclones détecté montre une corrélation modérée avec le GES à l'échelle mondiale (r = 0.71). Cependant, cette moyenne dissimule une réalité hémisphérique contrastée :
Hémisphère Nord : corrélation faible entre cyclones et température (r = 0.52) et GES (r = 0.69) Hémisphère Sud : corrélation très forte avec la température (r = 0.86) et le GES (r = 0.89)
Cette disparité suggère que les facteurs climatiques régissant la génération et l'intensité des cyclones varient significativement selon la latitude. Le Sud, dominé par les océans et les régions tropicales, montre une sensibilité bien supérieure aux modifications thermiques globales.
L'étude révèle des corrélations, pas des causalités directes pour les cyclones. Cependant les connaissances scientifiques permettent d'identifier une causalité entre les émissions de gaz à effets de serres sur l'augmentation des températures, et la multiplcation des catastrophes naturelles. D'autres facteurs environnementaux (intensification des modes d'agriculture, déforestation..), mais également politiques (économie mondialisée, délocalisation d'activités industrielles), permettraient d'affiner ces constats.
BIBLIOGRAPHIE¶
Hansen, J., R. Ruedy, M. Sato, and K. Lo, 2010: Global surface temperature change. Rev. Geophys., 48, RG4004, doi:10.1029/2010RG000345 https://www.giss.nasa.gov/pubs/docs/2010/2010_Hansen_ha00510u.pdf
Lenssen, N., G.A. Schmidt, M. Hendrickson, P. Jacobs, M. Menne, and R. Ruedy, 2024: A GISTEMPv4 observational uncertainty ensemble. J. Geophys. Res. Atmos., 129, no. 17, e2023JD040179, doi:10.1029/2023JD040179. https://essopenarchive.org/users/678317/articles/1115255-a-nasa-gistempv4-observational-uncertainty-ensemble
GISTEMP Team, 2025: GISS Surface Temperature Analysis (GISTEMP), version 4. NASA Goddard Institute for Space Studies. Dataset accessed 2025-08-10 at https://data.giss.nasa.gov/gistemp/.
Lenssen, N., G.A. Schmidt, M. Hendrickson, P. Jacobs, M. Menne, and R. Ruedy, 2024: A GISTEMPv4 observational uncertainty ensemble. J. Geophys. Res. Atmos., 129, no. 17, e2023JD040179, doi:10.1029/2023JD040179.
Knapp, K. R., M. C. Kruk, D. H. Levinson, H. J. Diamond, and C. J. Neumann, 2010: The International Best Track Archive for Climate Stewardship (IBTrACS): Unifying tropical cyclone best track data. Bulletin of the American Meteorological Society, 91, 363-376. doi:10.1175/2009BAMS2755.1
Gahtan, J., K. R. Knapp, C. J. Schreck, H. J. Diamond, J. P. Kossin, M. C. Kruk, 2024: International Best Track Archive for Climate Stewardship (IBTrACS) Project, Version 4r01. ['ibtracs.ALL.list.v04r01.csv']. NOAA National Centers for Environmental Information. doi:10.25921/82ty-9e16 [2025-11-09].